home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / edit / tde40.zip / diff.c < prev    next >
C/C++ Source or Header  |  1994-06-05  |  25KB  |  757 lines

  1. /*
  2.  * Being that the windows in TDE are numbered and lettered, we can easily
  3.  * prompt for windows to diff.  Might as well do a few standard diff
  4.  * options:  ignore leading space, ignore all space, ignore blank lines,
  5.  * ignore end-of-line, and Ignore/Match case.  Once the diff is defined,
  6.  * just press one key to find the next diff.  Any two visible windows may
  7.  * be diffed, which is really nice for comparing similar functions or
  8.  * data in seperate areas of a file.
  9.  *
  10.  *
  11.  * New editor name:  TDE, the Thomson-Davis Editor.
  12.  * Author:           Frank Davis
  13.  * Date:             June 5, 1991, version 1.0
  14.  * Date:             July 29, 1991, version 1.1
  15.  * Date:             October 5, 1991, version 1.2
  16.  * Date:             January 20, 1992, version 1.3
  17.  * Date:             February 17, 1992, version 1.4
  18.  * Date:             April 1, 1992, version 1.5
  19.  * Date:             June 5, 1992, version 2.0
  20.  * Date:             October 31, 1992, version 2.1
  21.  * Date:             April 1, 1993, version 2.2
  22.  * Date:             June 5, 1993, version 3.0
  23.  * Date:             August 29, 1993, version 3.1
  24.  * Date:             November 13, 1993, version 3.2
  25.  * Date:             June 5, 1994, version 4.0
  26.  *
  27.  * This code is released into the public domain, Frank Davis.
  28.  * You may distribute it freely.
  29.  */
  30.  
  31. #include "tdestr.h"
  32. #include "common.h"
  33. #include "define.h"
  34. #include "tdefunc.h"
  35.  
  36.  
  37. /*
  38.  * Name:    define_diff
  39.  * Purpose: get info needed to initialize diff
  40.  * Date:    October 31, 1992
  41.  * Passed:  window:  pointer to current window
  42.  * Notes:   allow the user to start the diff at the beginning of the
  43.  *            file or at the current cursor location.  once the diff
  44.  *            has been defined, the user may press one key to diff again.
  45.  *          user may diff any two visible windows on the screen.
  46.  */
  47. int  define_diff( TDE_WIN *window )
  48. {
  49. int  rc;
  50. int  num1;
  51. int  let1;
  52. int  num2;
  53. int  let2;
  54. int  start;
  55. char temp[MAX_COLS+2];
  56. char answer[MAX_COLS+2];
  57. #if defined( __UNIX__ )
  58.  chtype display_buff[MAX_COLS+2];       /* chtype is defined in curses.h */
  59. #else
  60.  char display_buff[(MAX_COLS+2)*2];
  61. #endif
  62.  
  63.    rc = OK;
  64.  
  65.    /*
  66.     * get window number and letter of the first diff window.  then,
  67.     *   verify that window - does it exit? is it visible?
  68.     */
  69.    if (rc == OK) {
  70.       *temp = '\0';
  71.       rc = get_name( diff_prompt1, window->bottom_line, temp,
  72.                      g_display.message_color );
  73.    }
  74.  
  75.    if (rc == OK) {
  76.       rc = verify_number( temp, &num1 );
  77.       if (rc == OK)
  78.          rc = verify_letter( temp, &let1, &diff.w1 );
  79.    }
  80.  
  81.    if (rc == ERROR) {
  82.       combine_strings( answer, diff_prompt6a, temp, diff_prompt6b );
  83.       error( WARNING, window->bottom_line, answer );
  84.       return( ERROR );
  85.    }
  86.  
  87.    /*
  88.     * get and verify the next window number and letter to diff.
  89.     */
  90.    *temp = '\0';
  91.    rc = get_name( diff_prompt2, window->bottom_line, temp,
  92.                   g_display.message_color );
  93.    if (rc == OK) {
  94.       rc = verify_number( temp, &num2 );
  95.       if (rc == OK)
  96.          rc = verify_letter( temp, &let2, &diff.w2 );
  97.    }
  98.    if (rc == ERROR) {
  99.       combine_strings( answer, diff_prompt6a, temp, diff_prompt6b );
  100.       error( WARNING, window->bottom_line, answer );
  101.       return( ERROR );
  102.    }
  103.  
  104.    /*
  105.     * are leading spaces significant?
  106.     */
  107.    save_screen_line( 0, window->bottom_line, display_buff );
  108.    set_prompt( diff_prompt7a, window->bottom_line );
  109.    start = get_yn( );
  110.    restore_screen_line( 0, window->bottom_line, display_buff );
  111.    if (start != ERROR)
  112.       diff.leading =  start == A_YES ?  TRUE  :  FALSE;
  113.    else
  114.       return( ERROR );
  115.  
  116.    /*
  117.     * are all spaces significant?
  118.     */
  119.    save_screen_line( 0, window->bottom_line, display_buff );
  120.    set_prompt( diff_prompt7b, window->bottom_line );
  121.    start = get_yn( );
  122.    restore_screen_line( 0, window->bottom_line, display_buff );
  123.    if (start != ERROR) {
  124.       if (start == A_YES)
  125.          diff.leading = diff.all_space = TRUE;
  126.       else
  127.          diff.all_space = FALSE;
  128.    } else
  129.       return( ERROR );
  130.  
  131.    /*
  132.     * are blank lines significant?
  133.     */
  134.    save_screen_line( 0, window->bottom_line, display_buff );
  135.    set_prompt( diff_prompt7c, window->bottom_line );
  136.    start = get_yn( );
  137.    restore_screen_line( 0, window->bottom_line, display_buff );
  138.    if (start != ERROR)
  139.       diff.blank_lines =  start == A_YES  ?  TRUE : FALSE;
  140.    else
  141.       return( ERROR );
  142.  
  143.    /*
  144.     * is end of line significant?
  145.     */
  146.    save_screen_line( 0, window->bottom_line, display_buff );
  147.    set_prompt( diff_prompt7d, window->bottom_line );
  148.    start = get_yn( );
  149.    restore_screen_line( 0, window->bottom_line, display_buff );
  150.    if (start != ERROR)
  151.       diff.ignore_eol =  start == A_YES  ?  TRUE : FALSE;
  152.    else
  153.       return( ERROR );
  154.  
  155.    /*
  156.     * now, find out were to start the diff -- beginning of file or
  157.     *   current cursor location.
  158.     */
  159.    save_screen_line( 0, window->bottom_line, display_buff );
  160.    set_prompt( diff_prompt3, window->bottom_line );
  161.    start = get_bc( );
  162.    restore_screen_line( 0, window->bottom_line, display_buff );
  163.  
  164.    if (start != ERROR) {
  165.       entab_linebuff( );
  166.       if (un_copy_line( window->ll, window, TRUE ) == ERROR)
  167.          return( ERROR );
  168.  
  169.       /*
  170.        * if everything is everything, initialize the diff pointers.
  171.        */
  172.       diff.defined = TRUE;
  173.       if (start == BEGINNING) {
  174.          diff.d1 = diff.w1->file_info->line_list;
  175.          diff.d2 = diff.w2->file_info->line_list;
  176.          diff.rline1 = 1L;
  177.          diff.rline2 = 1L;
  178.          diff.bin_offset1 = 0;
  179.          diff.bin_offset2 = 0;
  180.          rc = differ( 0, 0, window->bottom_line );
  181.       } else {
  182.          diff.d1 = diff.w1->ll;
  183.          diff.d2 = diff.w2->ll;
  184.          diff.rline1 = diff.w1->rline;
  185.          diff.rline2 = diff.w2->rline;
  186.          diff.bin_offset1 = diff.w1->bin_offset;
  187.          diff.bin_offset2 = diff.w2->bin_offset;
  188.          rc = differ( diff.w1->rcol, diff.w2->rcol, window->bottom_line );
  189.       }
  190.    }
  191.    return( rc );
  192. }
  193.  
  194.  
  195. /*
  196.  * Name:    repeat_diff
  197.  * Purpose: compare two cursor positions
  198.  * Date:    October 31, 1992
  199.  * Passed:  window:  pointer to current window
  200.  * Notes:   user may press this key at any time once the diff has been
  201.  *            defined.
  202.  */
  203. int  repeat_diff( TDE_WIN *window )
  204. {
  205. register int rc = ERROR;
  206.  
  207.    if (diff.defined) {
  208.       entab_linebuff( );
  209.       if (un_copy_line( window->ll, window, TRUE ) == ERROR)
  210.          return( ERROR );
  211.  
  212.       /*
  213.        * initialize the diff pointers.
  214.        */
  215.       diff.d1 = diff.w1->ll;
  216.       diff.d2 = diff.w2->ll;
  217.       diff.rline1 = diff.w1->rline;
  218.       diff.rline2 = diff.w2->rline;
  219.       diff.bin_offset1 = diff.w1->bin_offset;
  220.       diff.bin_offset2 = diff.w2->bin_offset;
  221.       rc = differ( diff.w1->rcol, diff.w2->rcol, window->bottom_line );
  222.    } else
  223.       error( WARNING, window->bottom_line, diff_prompt5 );
  224.    return( rc );
  225. }
  226.  
  227.  
  228. /*
  229.  * Name:    differ
  230.  * Purpose: diff text pointers
  231.  * Date:    October 31, 1992
  232.  * Passed:  initial_rcol1:  beginning column to begin diff in window1
  233.  *          initial_rcol2:  beginning column to begin diff in window2
  234.  *          bottom:         line to display diagnostics
  235.  * Notes:   a straight diff on text pointers is simple; however, diffing
  236.  *            with leading spaces and tabs is kinda messy.  let's do the
  237.  *            messy diff.
  238.  */
  239. int  differ( int initial_rcol1, int initial_rcol2, int bottom )
  240. {
  241. int  rcol1;             /* virtual real column on diff window 1 */
  242. int  rcol2;             /* virtual real column on diff window 2 */
  243. int  r1;                /* real real column rcol1 - needed for tabs */
  244. int  r2;                /* real real column rcol2 - needed for tabs */
  245. char c1;                /* character under r1 */
  246. char c2;                /* character under r2 */
  247. int  leading1;          /* adjustment for leading space in window 1 */
  248. int  leading2;          /* adjustment for leading space in window 2 */
  249. int  len1;              /* length of di